//
// Created by 夏申频 on 16/9/16.
//

#include "JPEGCodec8.h"
#include "JPEGCodec12.h"
#include "JPEGCodec16.h"

namespace JPEG{
    ImageInputStream::~ImageInputStream() {}
    ImageOutputStream::~ImageOutputStream() {}
    CoderCommon::~CoderCommon(){}
    ImageCodecErrorHandler::~ImageCodecErrorHandler(){}
    Decoder::~Decoder(){}
    Encoder::~Encoder(){}


    void LongJumpErrorHandler::onError(CoderCommon* coder){
        longjmp(setjmp_buffer, 1);
    }
    LongJumpErrorHandler::~LongJumpErrorHandler() {

    }

    STDImageInputStream::STDImageInputStream(std::istream& is):iStream(is){

    }
    STDImageInputStream::~STDImageInputStream(){

    }
    int STDImageInputStream::available(){
        std::streampos pos = iStream.tellg();
        std::streampos end = iStream.seekg(0, std::ios::end).tellg();
        iStream.seekg(pos, std::ios::beg);
        return end-pos;
    }
    int STDImageInputStream::read(ImageBuf& buf,size_t offset,size_t len){
        size_t  buffSize = buf.size()-offset;
        JOCTET * p = buf.data()+offset;
        int readSize = len<buffSize?len:buffSize;

        iStream.read((char*)p,readSize);

        return iStream.gcount();
    }

    STDImageOutputStream::STDImageOutputStream(std::ostream& os):oStream(os){

    }
    STDImageOutputStream::~STDImageOutputStream(){
        flush();
    }
    void STDImageOutputStream::write(const ImageBuf& buf,size_t offset,size_t len){
        size_t  buffSize = buf.size()-offset;
        const JOCTET* p = buf.data()+ offset;
        int writeSize = len<buffSize?len:buffSize;
        oStream.write((const char*)(p),writeSize);
    }
    void STDImageOutputStream::flush(){
        oStream.flush();
    }

    Decoder* jpegDecoder(int bit){
        Decoder* decoder = NULL;
        switch (bit){
            case 8:
                decoder = dynamic_cast<Decoder* >((new JPEG8::Decoder)->initCoder());
                break;
            case 12:
                decoder = dynamic_cast<Decoder* >((new JPEG12::Decoder)->initCoder());
                break;
            case 16:
                decoder = dynamic_cast<Decoder* >((new JPEG16::Decoder)->initCoder());
                break;

        }
        return decoder;
    }
    Encoder* jpegEncoder(int bit){
        Encoder* encoder = NULL;
        switch (bit){
            case 8:
                encoder = dynamic_cast<Encoder* >((new JPEG8::Encoder)->initCoder());
                break;
            case 12:
                encoder = dynamic_cast<Encoder* >((new JPEG12::Encoder)->initCoder());
                break;
            case 16:
                encoder = dynamic_cast<Encoder* >((new JPEG16::Encoder)->initCoder());
                break;
        }
        return encoder;
    }

    int putValueToImageBuf(ImageBuf& buf,size_t pos,JOCTET value){
        if (pos<buf.size()){
            buf[pos] = value;
            return 1;
        }
        return 0;
    }

    int putValueToImageBuf(ImageBuf& buf,size_t pos,JOCTET* buffer,size_t bufferSize){
        size_t bufSize = buf.size();
        size_t bufferAvailable = bufSize - pos;
        size_t len = bufferSize<bufferAvailable?bufferSize:bufferAvailable;

        for (int i = 0; i <len ; ++i) {
            buf[i+pos] = buffer[i];
        }

        return len;

    }
    const JOCTET* getImageBufPointer(const ImageBuf& buf){
        return buf.data();
    }
}


